﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading;
using System.Web;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using Medianamik.Core;
using Medianamik.Core.Configuration;
using Medianamik.Core.Interfaces;
using Medianamik.Core.Profile;
using Medianamik.Core.Querying;
using Medianamik.Core.Sugar;
using Medianamik.Globalization;
using Telerik.Web.UI;

namespace Medianamik.UI.Controls
{
    public class MedianamikLinkPicker : CompositeControl
    {
        #region Fields

        private readonly RadTreeView _treeview = new RadTreeView();
        private static readonly MedianamikConfigSection Config =
            (MedianamikConfigSection)ConfigurationManager
            .GetSection(ConfigurationSectionName.MEDIANAMIK);
        private readonly System.Web.UI.WebControls.DropDownList _langChoice =
            new System.Web.UI.WebControls.DropDownList();
        private readonly TextBox _anchor = new TextBox();
        private readonly TextBox _hidden = new TextBox();

        #endregion

        #region Events

        protected override void OnInit(EventArgs e)
        {
            base.OnInit(e);

            var cultureName = Config.DefaultEditionCultureName;

            if (Page.User.Identity.IsAuthenticated)
            {
                var profile = (UserProfile)HttpContext.Current.Profile;

                if (!string.IsNullOrEmpty(profile.UICultureName))
                    cultureName = profile.UICultureName;
            }

            Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo(cultureName);
        }

        private void NodeExpand(object sender, RadTreeNodeEventArgs e)
        {
            ExpandNode(e.Node, false);
        }

        void LangChoiceChanged(object sender, EventArgs e)
        {
            EditionCultureName = _langChoice.SelectedValue;
            LoadRootNodes();
        }

        #endregion

        #region Properties

        public string EditionCultureName
        {
            get
            {
                var editionCultureName = ViewState["EditionCultureName"] as string;

                if (editionCultureName == null)
                {
                    if (DialogParameters.Contains("EditionCultureName")
                    && DialogParameters["EditionCultureName"] != null)
                        ViewState["EditionCultureName"] = editionCultureName = DialogParameters["EditionCultureName"].ToString();
                }

                if (editionCultureName == null)
                {
                    ViewState["EditionCultureName"] = editionCultureName = MedianamikContext.Current.EditionCulture.Name;
                }

                return editionCultureName;
            }
            set { ViewState["EditionCultureName"] = value; }
        }

        private DialogParameters _dialogParameters;
        public DialogParameters DialogParameters
        {
            get
            {
                if (_dialogParameters == null)
                    _dialogParameters = DialogHandler.GetDialogParameters(this);

                return _dialogParameters;
            }
        }

        private MedianamikModule _currentModule;
        public MedianamikModule CurrentModule
        {
            get
            {
                if (_currentModule == null)
                {
                    var parameters = DialogHandlerNoSession.GetDialogParameters(this);
                }

                return _currentModule;
            }
        }

        private Node _selectedNode;
        public Node SelectedNode
        {
            get
            {
                if (_selectedNode == null && SelectedNodeId.HasValue)
                {
                    _selectedNode = NodeManager.GetNode(SelectedNodeId.Value);

                    if (_selectedNode != null)
                        _selectedNode.DefaultCulture = new CultureInfo(EditionCultureName);
                }

                return _selectedNode;
            }
        }

        private Guid? _selectedNodeId;
        public Guid? SelectedNodeId
        {
            get
            {
                if(_selectedNodeId == null && _hidden.Text.Length > 0)
                {
                    var value = _hidden.Text;
                }

                return _selectedNodeId;
            }
        }

        #endregion

        #region Methods

        private void ExpandNode(RadTreeNode node, bool selected)
        {
            ExpandNode(node, selected, null);
        }

        protected override void CreateChildControls()
        {
            Controls.Add(new RadAjaxManager());

            #region Main Div

            var mainDiv = new HtmlGenericControl("div");
            Controls.Add(mainDiv);
            mainDiv.Attributes.Add("class", "CorpsPopup");

            #region Lang Choice

            mainDiv.Controls.Add(_langChoice);
            _langChoice.SelectedIndexChanged += LangChoiceChanged;
            _langChoice.AutoPostBack = true;

            #endregion

            #region Hidden Field

            mainDiv.Controls.Add(_hidden);

            #endregion

            #region TreeView

            var treeDiv = new HtmlGenericControl("div");
            mainDiv.Controls.Add(treeDiv);
            treeDiv.Attributes.Add("class", "BlocArbo");
            treeDiv.Controls.Add(_treeview);
            _treeview.NodeExpand += NodeExpand;

            #endregion

            #region Anchor

            var para = new HtmlGenericControl("p");
            mainDiv.Controls.Add(para);
            var label = new HtmlGenericControl("label")
                {
                    InnerText = Translator.Translate("Medianamik_ContentManagement", "AnchorLabel")
                };
            para.Controls.Add(label);
            para.Controls.Add(_anchor);

            #endregion

            #region Buttons

            var buttonsCssLiteral1 = new Literal();
            mainDiv.Controls.Add(buttonsCssLiteral1);
            var selectButton = new Button();
            mainDiv.Controls.Add(selectButton);
            var space = new Literal();
            mainDiv.Controls.Add(space);
            var cancelButton = new Button();
            mainDiv.Controls.Add(cancelButton);
            var buttonsCssLiteral2 = new Literal();
            mainDiv.Controls.Add(buttonsCssLiteral2);

            #endregion

            #endregion

            if (!Page.IsPostBack) //ViewState s'en occupe
            {
                #region Lang Choice

                _langChoice.DataSource = ConfigManager.GetEditionCultures().Select(c => new CultureInfo(c.CultureName));
                _langChoice.DataTextField = "DisplayName";
                _langChoice.DataValueField = "Name";
                _langChoice.DataBind();
                _langChoice.SelectedValue = EditionCultureName;
                _langChoice.CssClass = "SelectList";

                #endregion

                #region Hidden Field

                

                #endregion

                #region TreeView

                LoadRootNodes();
                _treeview.Skin = "Medianamik";
                _treeview.EnableEmbeddedSkins = false;
                _treeview.Width = 222;
                _treeview.Height = 295;

                #endregion

                #region Anchor

                if (DialogParameters.ContainsKey("Anchor") && DialogParameters["Anchor"] != null)
                    _anchor.Text = DialogParameters["Anchor"].ToString();

                #endregion

                #region Buttons

                selectButton.Text = Translator.Translate("Medianamik_ContentManagement", "MedianamikTemplateSelect");
                selectButton.OnClientClick = "insertLink();return false;";
                selectButton.CssClass = "Btn";

                space.Text = "&nbsp;";

                cancelButton.Text = Translator.Translate("Medianamik_ContentManagement", "MedianamikTemplateCancel");
                cancelButton.OnClientClick = "getRadWindow().close();";
                cancelButton.CssClass = "Btn";

                buttonsCssLiteral1.Text = "<p style=\"clear:both; margin-top: 20px;\">";
                buttonsCssLiteral2.Text = "</p>";

                #endregion
            }
        }

        private void LoadRootNodes()
        {
            _treeview.Nodes.Clear();
            var rootTreeNode = CreateTreeNode(CurrentModule);
            rootTreeNode.ExpandMode = TreeNodeExpandMode.ServerSide;
            _treeview.Nodes.Add(rootTreeNode);
            ExpandNode(rootTreeNode, false, CurrentModule);

            if (SelectedNodeId.HasValue && SelectedNodeId.Value != CurrentModule.ID)
            {
                GoToSelectedNodeId();
            }
        }

        private void GoToSelectedNodeId()
        {
            if (_treeview.Nodes.Count < 1)
                LoadRootNodes();

            if (_treeview.Nodes.Count > 0)
            {
                var selectedTreeNode = _treeview.FindNodeByValue(SelectedNodeId.GetValueOrDefault(CurrentModule.ID).ToString());

                //Si le noeud n'est pas dans l'arbre
                if (selectedTreeNode == null)
                {
                    //Trouver le parent déjà dans l'arbre
                    var parentIDs = SelectedNode.GetParentIDs(true);
                    var i = 0;

                    while (selectedTreeNode == null && i < parentIDs.Count())
                    {
                        selectedTreeNode = _treeview.FindNodeByValue(parentIDs.ElementAt(i).ToString());
                        i++;
                    }

                    //Expand parent node until SelectedNodeId reached
                    for (var j = i - 1; j >= 0; j--)
                    {
                        ExpandNode(selectedTreeNode, false);

                        if (j - 1 > 0)
                        {
                            selectedTreeNode = selectedTreeNode.Nodes
                                .FindNodeByValue(parentIDs.ElementAt(j - 1).ToString());
                        }
                    }

                    selectedTreeNode = selectedTreeNode.Nodes.FindNodeByValue(SelectedNodeId.Value.ToString());
                }

                ExpandNode(selectedTreeNode, true, SelectedNode);
            }
        }

        private void ExpandNode(RadTreeNode node, bool selected, INode rootNode)
        {
            if (selected)
            {
                _treeview.ClearSelectedNodes();
            }

            if (node == null)
                throw new ApplicationException("The parent node is not part of the hierarchy.");

            if (node.ExpandMode == TreeNodeExpandMode.ServerSide)
            {
                var parentNode = rootNode ?? NodeManager.GetNode(new Guid(node.Value));

                foreach (var item in parentNode.GetChildContentNodes(new CultureInfo(EditionCultureName))
                    .Where(n => !n.NodeType.IsSystem))
                {
                    var newNode = CreateTreeNode(item);

                    if (item.HasChildren)
                    {
                        newNode.ExpandMode = TreeNodeExpandMode.ServerSide;
                    }

                    node.Nodes.Add(newNode);
                }

                node.ExpandMode = TreeNodeExpandMode.ClientSide;
            }

            node.Expanded = true;
            node.ExpandParentNodes();
            node.Selected = selected;
        }

        protected override void Render(HtmlTextWriter writer)
        {
            const string script = @"
                <script type=""text/javascript"">
                    function getRadWindow(){{
                        if (window.radWindow){{return window.radWindow;}}
                        if (window.frameElement && window.frameElement.radWindow){{return window.frameElement.radWindow;}}
                                return null;
                    }}
                    
                    function initDialog(){{
                        var clientParameters = getRadWindow().ClientParameters;
                        var hidden = $get('{0}');
                        hidden.value = clientParameters.href;
                        alert(hidden.value);
                    }}

                    if (window.attachEvent){{window.attachEvent(""onload"", initDialog);}}
                    else if (window.addEventListener){{window.addEventListener(""load"", initDialog, false);}}
                    
                    function insertLink(sender, eventArgs){{
                        var treeview = $find('{1}');
                        var nodes = treeview.get_selectedNodes();
                        if(nodes.length > 0) {{
                            var node = nodes[0];
                            if (node.get_category() == ""Disabled"") {{
                                alert('todo');
                            }}
                            else {{
                                var closeArgument = {{}}; 
                                closeArgument.href = "".@"" + node.get_value() + "".@"";
                                closeArgument.text = node.get_text();
                                closeArgument.nodeid = node.get_value();
                                getRadWindow().close(closeArgument);
                            }}
                        }}
                        else
                            alert('todo');
                    }}
                </script>";

            writer.Write(String.Format(script, _hidden.ClientID, _treeview.ClientID));
            base.Render(writer);
        }

        private RadTreeNode CreateTreeNode(INode node)
        {
            var result = new RadTreeNode
            {
                Text = node.DisplayName,
                Value = node.ID.ToString(),
                ImageUrl = node.NodeType.IconPath ?? String.Empty,
            };

            if (!node.NodeType.IsChildOf(MedianamikTypes.BaseWebType) ||
                !node.Instances.Exists(EditionCultureName))
            {
                result.Category = "Disabled";
                result.CssClass += " rtDisabled";
            }

            return result;
        }

        #endregion
    }
}
